package com.uu.it.tracker.computation;

import com.uu.it.tracker.sensordata.SensorData.Gestures;

import android.os.Parcel;
import android.os.Parcelable;

public class Calculator {
	/**
	 * status constants
	 * */
	public final static String WALKING = "walking";
	public final static String RUNNING = "running";
	public final static String STANDING = "standing";
	/**
	 * Unit is m/s
	 * */
	private float normalWalkingSpeed = new Float(2);
	private float normalRunningSpeed = 6;
	private float normalStandingSpeed = 0;
	
	public static class StatusBand{
		int x;
		int y;
		
		public StatusBand(int Xband, int Yband){
			x = Xband;
			y = Yband;
		}
		public static boolean isInXRange(int data, StatusBand lBand, StatusBand upBand){
			if(data >= lBand.x && data < upBand.x)
				return true;
			else return false;
		}
		public static boolean isInYRange(int data, StatusBand lBand, StatusBand upBand){
			if(data >= lBand.y && data < upBand.y)
				return true;
			else return false;			
		}
		public static float computeXYProportion(int X, int Y, 
				StatusBand lBand, StatusBand upBand){
			float rangLength = (upBand.x + upBand.y) - (lBand.x + lBand.y);
			float value = (X + Y) - (lBand.x + lBand.y);
			return (value / rangLength) + new Float(0.5);
		}
	}

	
	public static class SportStatus implements Parcelable{
		
		/**
		 * Speed of the movement, unit m/s
		 * */
		private float _speed;
		
		/**
		 * standing, walking, or running
		 * */
		private String _status;
		
		public static final Parcelable.Creator<SportStatus> CREATOR
				= new Parcelable.Creator<SportStatus>() {
			public SportStatus createFromParcel(Parcel in) {
				return new SportStatus(in);
			}	
			public SportStatus[] newArray(int size) {
				return new SportStatus[size];
			}
		};
		
		public SportStatus(String status, float speed){
			_status = status;
			_speed = speed;
		}
		
		private SportStatus(Parcel in) {
			_speed = in.readFloat();
			_status = in.readString();
		}
		
		public void writeToParcel(Parcel dest, int flags) {
			// TODO Auto-generated method stub
			dest.writeFloat(_speed);
			dest.writeString(_status);
		} 
		
		public String getStatus(){
			return _status;
		}
		
		public float getSpeed(){
			return _speed;
		}
		
		public int describeContents() {
			// TODO Auto-generated method stub
			return 0;
		}
		
		public String toString() {
			return "Status = " + _status + ", Speed = " + _speed;
		}
	}

	/**
	 * Compute the speed and the status from current data
	 * WSN group provides us threshold of different movements. We judge the status
	 * of user based on the threshold.
	 * Speed is computed from the proportion of normal speeds.
	 * */
	public SportStatus processData(TrackerData data) {
		float speed = 0;
		SportStatus status;
		
		if(data.isInRunningRange()){
			speed = data.computeProportion(Gestures.RUN) * normalRunningSpeed;
			status = new SportStatus(RUNNING, speed);
		}
		else if(data.isInWalkingRange()){
			speed = data.computeProportion(Gestures.WALK) * normalWalkingSpeed;
			status = new SportStatus(WALKING, speed);
		}
		else if(data.isInStandingRange()){
			speed =  data.computeProportion(Gestures.STAND) * normalStandingSpeed;
			status = new SportStatus(STANDING, speed);
		}
		//data is not in any range, should throw exception or return null
		else status = null;
		
		return status;
	}
}
